<?php
declare (strict_types=1);

namespace app\scan_bag\controller;

use app\admin\model\advertiser\AdvertiserThird;
use app\admin\model\base\User;
use app\admin\model\iot\ScanBagDay;
use app\admin\model\iot\ScanBagWay;
use app\admin\service\base\JwtService;
use app\BaseController;
use app\BaseService;
use app\scan_bag\service\ScanBagV2Service;
use think\App;
use think\facade\Cache;
use think\response\Json;
use wechat\ScanBagMiniProgram;
use wechat\WsOfficialAccount;

/**
 * 微信V2_Way_2_0扫码取袋
 */
class V2_Way_2_0 extends BaseController
{

    /**
     * 当前扫码路径
     * @var string
     */
    private string $way = 'V2_Way_2_0';

    /**
     * 微信H5用户登录
     * @param ScanBagV2Service $scanBagV2Service
     * @return Json
     */
    public function wechatLogin(ScanBagV2Service $scanBagV2Service): Json
    {
        //接受参数
        $code = $this->request->param('code/s', '');
        //微信解析code
        $bool = $scanBagV2Service->wechatH5Login2($code);
        if ($bool['bool']) {
            //签发token
            $jst_data = JwtService::authorizations('scan_bag', $bool['user_id'], 3600);
            if ($jst_data['bool']) {
                return jsonReturn(1, $bool, '登录成功');
            }
        }
        return jsonReturn(0, [], '签发token失败');
    }

    /**
     * 微信H5用户取袋次数
     * @return Json
     */
    public function userScanNum(): Json
    {
        $user_id = WS_USER_ID;
        $day = ScanBagDay::getUserIdDayNum($user_id);
        return jsonReturn(1, $day);
    }

    /**
     * 微信H5公众号二维码
     * @return Json
     */
    public function wechatQrcode(): Json
    {
        //接受参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s');
        if (!$mac_id) {
            return jsonReturn(0, [], 'MacID参数错误');
        }
        //默认值
        $name = $appid = $qrcode = '';
        $is_qrcode = false;
        //对接聚合平台
        $WayInfo = ScanBagWay::getMacIdWay($mac_id);
        if (!$WayInfo or $WayInfo['key'] != $this->way) {
            return jsonReturn(0, [], '当前设备路径错误,请联系管理员!');
        }
        //获取推广的公众号
        $OfficialAccount = AdvertiserThird::getIdOfficialAccount($user_id, $WayInfo['third_official'], $mac_id);
        if ($OfficialAccount) {
            $name = $OfficialAccount['name'];
            $appid = $OfficialAccount['appid'];
            $qrcode = $OfficialAccount['qrcode'];
            $is_qrcode = true;
        }
        //没有关注和没有第三方二维码则显示兜底二维码
        if (!$name or !$appid or !$qrcode) {
            $sys_config = config('sys_config.WsOfficialAccount');
            //未关注默认主体公众号二维码
            $name = $sys_config['name'];
            $appid = $sys_config['appid'];
            //获取带参数的二维码url
            $Ws = new WsOfficialAccount();
            $qrcode = $Ws->temporaryQrcode('scan_bag');
        }
        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 1);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描设备二维码');
        }
        //返回数据
        $data = ['name' => $name, 'appid' => $appid, 'qrcode' => $qrcode, 'is_qrcode' => $is_qrcode];
        return jsonReturn(1, $data);
    }

    /**
     * 微信H5识别二维码
     * @return Json
     */
    public function qrcodeDiscern(): Json
    {
        //接受参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s');
        if (!$mac_id) {
            return jsonReturn(0, [], 'MacID参数错误');
        }
        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 2);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描设备二维码');
        }
        return jsonReturn(1, []);
    }

    /**
     * 获取JSAPI配置
     * @return Json
     */
    public function jsApiConfig(): Json
    {
        //接受参数
        $url = $this->request->param('url/s', '');
        $obj = new WsOfficialAccount();
        $data = $obj->getJsApi($url);;
        return jsonReturn(1, $data);
    }

    /**
     * 微信上传经纬度信息
     * @return Json
     */
    public function wechatLatLon(): Json
    {
        //接受参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s');
        $latitude = $this->request->param('latitude/s', '0');
        $longitude = $this->request->param('longitude/s', '0');
        if (!$mac_id) {
            return jsonReturn(0, [], 'MacID参数错误');
        }
        //把地理位置信息保存至用户表
        User::userLocationRedis($user_id, $mac_id, $latitude, $longitude);
        //微信验证上传经纬度信息
        $bool = ScanBagV2Service::verifyLatLon($mac_id, $latitude, $longitude);
//        if ($bool) {
            //标记取袋安全码
            $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 3);
            if (!$SafeCode) {
                return jsonReturn(0, [], '请重新扫描设备二维码');
            }
            return jsonReturn(1, [], '验证通过');
//        }
        return jsonReturn(0, [], '您的位置距离设备太远,请移步设备前扫码免费领取。');
    }

    /**
     * 微信小程序URLScheme
     * @return Json
     */
    public function getURLScheme(): Json
    {
        //接收参数
        $params = $this->request->param();
        if (!isset($params['mac_id']) or !$params['mac_id']) {
            return jsonReturn(0, [], '设备参数错误,请联系管理员!');
        }
        //获取用户信息
        $user_id = WS_USER_ID;
        $User = User::getIdUserInfo($user_id);
        $params['open_id'] = $User['openid'];
        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $params['mac_id'], 4);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描设备二维码');
        }
        //通过mac_id获取路径
        $WayInfo = ScanBagWay::getMacIdWay($params['mac_id']);
        if ($WayInfo['key'] != $this->way) {
            return jsonReturn(0, [], '路径参数错误,请联系管理员');
        }
        //生成取袋路径微信小程序码
        $wechat = new ScanBagMiniProgram($WayInfo);
        $path = $WayInfo['mini_link'] ?? 'pages/index/index';
        //增加取袋码
        $params['way'] = $WayInfo['key'];
        $params['waycode'] = ScanBagV2Service::generateBagOutWaycode($User, $WayInfo['key'], $params['mac_id']);
        //收到打开时需要的参数
        $data['miniPath'] = $path . '?' . http_build_query(array_unique($params));
        //则生成取袋路径微信小程序码
        $data['scheme'] = $wechat->URLScheme($path, http_build_query($params));
        $code = $data['scheme']['bool'] ? 1 : 0;
        return jsonReturn($code, $data);
    }

    /**
     * 无塑地球微信小程序用户登录
     * @param ScanBagV2Service $scanBagV2Service
     * @return Json
     */
    public function miniProgramLogin(ScanBagV2Service $scanBagV2Service): Json
    {
        //接受参数
        $appid = $this->request->param('appid/s', '');
        $code = $this->request->param('code/s', '');
        //微信解析code
        $bool = $scanBagV2Service->miniProgramLogin($appid, $code);
        if ($bool['bool']) {
            //通过用户id获取取袋token
            $is_token = JwtService::getUserToken('scan_bag', $bool['user_id']);
            if ($is_token) {
                return jsonReturn(1, $bool, '登录成功');
            } else {
                //没有token则签发token
                $jst_data = JwtService::authorizations('scan_bag', $bool['user_id'], 3600);
                if ($jst_data['bool']) {
                    //返回数据
                    return jsonReturn(1, $bool, '登录成功');
                }
            }
        }
        return jsonReturn(0, [], '签发token失败');
    }

    /**
     * 微信小程序广告ID
     * @param ScanBagV2Service $scanBagV2Service
     * @return Json
     */
    public function miniProgramAdvert(ScanBagV2Service $scanBagV2Service): Json
    {
        //接收参数
        $appid = $this->request->param('appid/s', '');
        $data = $scanBagV2Service->miniProgramAdvert($appid);
        if ($data['bool']) {
            return jsonReturn(1, $data['advert']);
        }
        return jsonReturn(0, []);
    }

    /**
     * 微信取袋码出袋
     * @return Json
     */
    public function postOutBag(): Json
    {
        //接收参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s', '');
        $way_code = $this->request->param('way_code/s', '');
        if(!$way_code){
            $way_code = $this->request->param('waycode/s', '');
        }
        //判断参数
        if (!$user_id or !$mac_id or !$way_code) {
            return jsonReturn(0, [], '参数错误');
        }
        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 5, true);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描设备二维码!');
        }
        //验证当前设备取袋路径
        $WayInfo = ScanBagWay::getMacIdWay($mac_id);
        if ($WayInfo['key'] != $this->way) {
            return jsonReturn(0, [], '当前设备路径错误,请联系管理员!');
        }
        //获取缓存当前用户经纬度
        $LatLon = Cache::get(BaseService::generateLocationKey($user_id));
        if (!$LatLon or !isset($LatLon['latitude']) or !isset($LatLon['longitude'])) {
            return jsonReturn(0, [], '您的位置授权失败,请重新扫描设备二维码!');
        }
        //验证地理位置
        $bool = ScanBagV2Service::verifyLatLon($mac_id, $LatLon['latitude'], $LatLon['longitude']);
        if (!$bool) {
            return jsonReturn(0, [], '您的位置距离设备太远,请移步设备前扫码免费领取!');
        }
        //执行出袋程序
        $res = ScanBagV2Service::bagOutProgram($way_code, $this->way, $user_id, $mac_id);
        if ($res['bool']) {
            return jsonReturn(1, $res['data'], $res['msg']);
        }
        return jsonReturn(0, [], $res['msg']);
    }

    /**
     * 微信取袋发起支付
     * @return Json
     */
    public function wechatPayOrder(): Json
    {
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id', '');
        //判断参数
        if (!$user_id or !$mac_id) {
            return jsonReturn(0, [], '用户信息或设备地址错误!');
        }
        //执行发起预支付
        $res = ScanBagV2Service::wechatPayOrder($user_id, $mac_id);
        if ($res['bool']) {
            return jsonReturn(1, $res['data'], $res['msg']);
        }
        return jsonReturn(0, [], $res['msg']);
    }

}
